#define CATCH_CONFIG_MAIN
#include <catch2/catch.hpp>

#include "bzbstring.h"
using namespace bzbstring;


TEST_CASE( "bzbstring::chomp is being tested", "[single-file]" ) {
	
	std::string string = "";
	chomp(string);
	REQUIRE( string == "" );

	string = "Test String\n";
	chomp(string);
	REQUIRE( string == "Test String" );

	string = "teststring";
	chomp(string);
	REQUIRE( string == "teststring" );

	string = "teststring\n\n";
	chomp(string);
	REQUIRE( string == "teststring\n" );
}


TEST_CASE( "bzbstring::trim is being tested", "[single-file]" ) {
	
	std::string string = "";
	trim(string);
	REQUIRE( string == "" );

	string = "Test String\n";
	trim(string);
	REQUIRE( string == "Test String" );

	string = "teststring";
	trim(string);
	REQUIRE( string == "teststring" );

	string = "teststring\n\n";
	trim(string);
	REQUIRE( string == "teststring" );

	string = "\t  \nteststring\n \t  \n";
	trim(string);
	REQUIRE( string == "teststring" );

	string = "\t\n \t\n";
	trim(string);
	REQUIRE( string == "" );
}


TEST_CASE( "bzbstring::split is being tested", "[single-file]" ) {

	std::vector<std::string> result;

	// Common behavior
	result = split("Lorem ipsum dolor sit amet");
	REQUIRE( result[0] == "Lorem" );
	REQUIRE( result[1] == "ipsum" );
	REQUIRE( result[2] == "dolor" );
	REQUIRE( result[3] == "sit" );
	REQUIRE( result[4] == "amet" );


	// Check initial split char
	result = split(" Hello\nFellow\nEarthlings! ");
	REQUIRE( result[0] == "Hello\nFellow\nEarthlings!" );


	// Check different split char
	result = split(" Hello\nFellow\nEarthlings! ", '\n');
	REQUIRE( result[0] == " Hello" );
	REQUIRE( result[1] == "Fellow" );
	REQUIRE( result[2] == "Earthlings! " );


	// Check initial, trailing and multiple split char
	result = split("  Lorem  ipsum  dolor   sit    amet ");
	REQUIRE( result[0] == "Lorem" );
	REQUIRE( result[1] == "ipsum" );
	REQUIRE( result[2] == "dolor" );
	REQUIRE( result[3] == "sit" );
	REQUIRE( result[4] == "amet" );

}


TEST_CASE( "bzbstring::concat is being tested", "[single-file]" ) {

	// Common behavior (different order)
	REQUIRE( concat("Hello", " Fellow ", "Earthlings", "!") == "Hello Fellow Earthlings!" );
	REQUIRE( concat("Hello Fellow ", "Earthlings!") == "Hello Fellow Earthlings!" );
	REQUIRE( concat("Hello", " Fellow Earthlings!") == "Hello Fellow Earthlings!" );

	// Support for numbers and other types of variables
	REQUIRE( concat("One Hundred is ", 100, ", while Pi is ", 3.14) ==
					"One Hundred is 100, while Pi is 3.14" );
	REQUIRE( concat(100, 101, 102) == "100101102" );
	REQUIRE( concat(100.5, 101.6, 102.7) == "100.5101.6102.7" );

}


TEST_CASE( "bzbstring::replace is being tested", "[single-file]" ) {

	std::string str;

	// Empty string
	replace(str, "a", "b");
	REQUIRE( str == "" );

	str = "Hello Fellow Earthlings!";

	// Empty replaced string
	replace(str, "", "a");
	REQUIRE( str == "Hello Fellow Earthlings!" );

	// Check deletions
	replace(str, " ", "");
	REQUIRE( str == "HelloFellowEarthlings!" );

	str = "Hello Fellow Earthlings!";

	// Common behavior
	replace(str, "Fellow", "Enemy");
	REQUIRE( str == "Hello Enemy Earthlings!" );

	str = "Hello Fellow Earthlings!";

	// Check for variable number of replacements
	replace(str, "e", "3", 1);
	REQUIRE( str == "H3llo Fellow Earthlings!" );

	str = "Hello Fellow Earthlings!";

	// Check for unwanted duplications
	replace(str, "!", "!!!", 1);
	REQUIRE( str == "Hello Fellow Earthlings!!!" );

	str = "Hello Fellow Earthlings!";

	// Check for infinite duplications
	replace(str, "!", "!!!");
	REQUIRE( str == "Hello Fellow Earthlings!!!" );

	str = "Hello! Fellow! Earthlings!";

	// Check for more complex and multiple possible duplications
	replace(str, "!", "?A!B!A?");
	REQUIRE( str == "Hello?A!B!A? Fellow?A!B!A? Earthlings?A!B!A?" );

}


TEST_CASE( "bzbstring::to_unix_path is being tested", "[single-file]" ) {

	// Empty string
	REQUIRE( to_unix_path("") == "" );

	// Common behavior
	REQUIRE( to_unix_path("C:\\Windows\\whatever\\") == "C:/Windows/whatever/" );
	REQUIRE( to_unix_path("\\/\\/\\/") == "//////" );

}


TEST_CASE( "bzbstring::hex is being tested", "[single-file]" ) {

	REQUIRE( hex(0) == "00" );
	REQUIRE( hex(1) == "01" );
	REQUIRE( hex(2) == "02" );
	REQUIRE( hex(16) == "10" );
	REQUIRE( hex(255) == "ff" );
	REQUIRE( hex(-1) == "ff" );

}


TEST_CASE( "bzbstring::base64_encode is being tested", "[single-file]" ) {

	REQUIRE( bzbstring::base64_encode("Hello World!") == "SGVsbG8gV29ybGQh" );
	REQUIRE( bzbstring::base64_encode("") == "" );

}


TEST_CASE( "bzbstring::base64_decode is being tested", "[single-file]" ) {

	REQUIRE( bzbstring::base64_decode("SGVsbG8gV29ybGQh") == "Hello World!" );
	REQUIRE( bzbstring::base64_encode("") == "" );

}
